package com.ruoyi.common.utils.security;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;

/**
 * API接口加密工具类
 * 
 * @author ruoyi
 */
public class ApiEncryptUtils
{
    private static final Logger log = LoggerFactory.getLogger(ApiEncryptUtils.class);

    /**
     * 默认密钥(可通过配置文件修改)
     */
    private static final String DEFAULT_KEY = "aW0t5adf1uNdP7jU";
    
    /**
     * 默认偏移量(可通过配置文件修改)
     */
    private static final String DEFAULT_IV = "RbmhNetworkRuoYi";
    
    /**
     * 加密算法
     */
    private static final String ALGORITHM = "AES";
    
    /**
     * 加密算法/工作模式/填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 加密数据
     * 
     * @param data 待加密数据
     * @return 加密后的数据
     */
    public static String encrypt(String data)
    {
        return encrypt(data, DEFAULT_KEY, DEFAULT_IV);
    }

    /**
     * 加密数据
     * 
     * @param data 待加密数据
     * @param key 密钥
     * @param iv 偏移量
     * @return 加密后的数据
     */
    public static String encrypt(String data, String key, String iv)
    {
        if (StringUtils.isEmpty(data))
        {
            return null;
        }
        try
        {
            byte[] keyBytes = getKeyBytes(key);
            byte[] ivBytes = getKeyBytes(iv);
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
            
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            
            byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        }
        catch (Exception e)
        {
            log.error("加密数据失败", e);
            throw new ServiceException("加密数据失败");
        }
    }

    /**
     * 解密数据
     * 
     * @param encryptedData 已加密数据
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData)
    {
        return decrypt(encryptedData, DEFAULT_KEY, DEFAULT_IV);
    }

    /**
     * 解密数据
     * 
     * @param encryptedData 已加密数据
     * @param key 密钥
     * @param iv 偏移量
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData, String key, String iv)
    {
        if (StringUtils.isEmpty(encryptedData))
        {
            return null;
        }
        try
        {
            byte[] keyBytes = getKeyBytes(key);
            byte[] ivBytes = getKeyBytes(iv);
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
            
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        }
        catch (Exception e)
        {
            log.error("解密数据失败", e);
            throw new ServiceException("解密数据失败");
        }
    }
    
    /**
     * 获取密钥字节数组(固定长度为16字节)
     * 
     * @param key 密钥
     * @return 密钥字节数组
     */
    private static byte[] getKeyBytes(String key)
    {
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
        byte[] result = new byte[16]; // AES-128需要16字节密钥
        
        // 如果密钥长度不足16字节，则填充0；如果超过16字节，则截取前16字节
        System.arraycopy(keyBytes, 0, result, 0, Math.min(keyBytes.length, result.length));
        return result;
    }
}